//
//  main.m
//  Memory5
//
//  Created by cora1n on 14-8-11.
//  Copyright (c) 2014年 devwu. All rights reserved.
//

#import <Foundation/Foundation.h>
@interface Cat : NSObject
@property (nonatomic,strong)NSString* name;
@end
@implementation Cat
-(void)dealloc
{
    NSLog(@"%@ 被释放",_name);
}


@end

//手动引用计数
//MRC -- Manual Reference Counting
//自动引用计数
//ARC -- Automatic Reference Counting

//ARC中撤销了用于内存管理的方法.


//retain relase autorelease retainCount 等方法不可在ARC中调用
//用于简化内存管理,
//将MRC中的一些操作弃用,通过语法分析,自动在合适的位置插入 release retain 等操作

//ARC 中增加了 一些用于内存造作的修饰符
//__weak     弱引用,相当于assign
//__strong   强引用,相当于retain

//ARC中使用 strong weak 来代替 retain assign
//变量
//__strong __weak __unsafe_unretained __autoreleasing

//属性
//strong weak

//1.1强引用,对象的成员变量被赋值时,会先将传入的变量增持一次
//当对象的成员变量发生改变时,会自动将其减持一次

//1.2弱引用,当对象的成员变量被赋值时,直接赋值,不发生增持操作

//2.1 strong/weak 与 retain/release 的区别
//使用strong 或者 weak 时,如果该对象已经被释放,指向该对象的指针会被自动置为 nil,避免出现野指针(悬垂指针)


//2.2 __unsafe_unretained 与 __weak类似
//但是,当对象被释放时,不发生重置操作..

//2.3 __autoreleasing 延迟释放

@interface Person : NSObject
{
    //实例变量默认为__strong
    NSString * _name;
    __unsafe_unretained Cat * _cat;
}
-(void)setCat:(Cat*)cat;
-(Cat*)cat;

-(void)setName:(NSString*)name;
-(NSString*)name;
//@property (nonatomic,strong) NSString * name;
@end
@implementation Person
-(void)setName:(NSString *)name
{
    _name = name;
}
-(NSString *)name
{
    //手写 getter 方法,不要使用形如 self.name 或 [self name]的操作
    //而应该直接返回 _name;
//    return self.name;
//    return [self name];
    return _name;
}
-(void)setCat:(Cat *)cat
{
    _cat = cat;
}
-(Cat *)cat
{
    return _cat;
}

-(void)dealloc
{
    NSLog(@"%@ 被释放",_name);
    //ARC 不需要调用 父类的dealloc
}

@end


//获取🐱的函数
//Cat* getCat()
//{
//    Cat * c = [[Cat alloc]init];
//    c.name  = @"狸猫";
//    return c;
//}


int main(int argc, const char * argv[])
{
    
//    Person * p1 = [[Person alloc]init];
////    p1.name = @"zhangsan";
//    [p1 setName:@"zhangsan"];
//    
//    [p1 setName:@"ni"];
//    
//    NSLog(@"程序结束");
    //ARC中在此处插入了一个如下操作
//    [p1 release];
    
    
    
    
    
//    Person * p2 = [[Person alloc]init];
//    [p2 setName:@"zhangsan"];
//    //p2 持有了c1
//    {
//        Cat * c1 = [[Cat alloc]init];
//        c1.name = @"波斯猫"; //1
//
//        Cat * c2 = [[Cat alloc]init];
//        c2.name = @"蓝短";//1
//        [p2 setCat:c1];//c1.retainCount ==  2
        
//        [p2 setCat:c2];//c2.retainCount ==  2
        
//        [p2 setCat:c1];
//    }
    
    //作用域超出时,如果该对象不被其他对象所使用,则会ARC机制会将其自动释放
    
    
//    NSLog(@"改变指向");
    //p2 改变指向,持有c2
    
    
//    zhangsan dealloc   c1(c2).retainCount -1
    
    
    //ARC中所有的变量,默认为__strong
    
    
//    Cat * c = [[Cat alloc]init];
//    //__weak 的对象 c 运行到该行时,已经被释放.
//    if (c==nil) {
//        NSLog(@"123");
//    }
//    //c 野指针
//    NSLog(@"333");
    
     {
         NSMutableArray * mArr = [[NSMutableArray alloc]init];
        for (int i =0; i<100; i++) {
            Cat * c = [[Cat alloc]init];
            [mArr addObject:c];
        }
        
    }
    
    return 0;
}

